using System;
using System.Collections.Generic;

using SBPweb.Modules.Modularity;
using SBPweb.Contracts.StateManagement;

namespace SBPweb.Contracts
{
	public interface IStateManagementService : IService
	{
		/// <summary>
		/// The currently selected state
		/// </summary>
		State CurrentState
		{
			get;
		}

		/// <summary>
		/// The currently selected mode
		/// </summary>
		Mode CurrentMode
		{
			get;
		}

		/// <summary>
		/// All states in the selected mode
		/// </summary>
		List<State> CurrentStates
		{
			get;
		}

		/// <summary>
		/// All states
		/// </summary>
		List<State> AllStates
		{
			get;
		}

		/// <summary>
		/// All modes
		/// </summary>
		List<Mode> AvailableModes
		{
			get;
		}

		/// <summary>
		/// All modes (with the states)
		/// </summary>
		Dictionary<Mode, List<State>> Modes
		{
			get;
		}

		/// <summary>
		/// Is this state locked?
		/// </summary>
		bool IsStateLocked
		{
			get;
		}

		/// <summary>
		/// Is this mode locked?
		/// </summary>
		bool IsModeLocked
		{
			get;
		}

        string Message
        {
            get;
            set;
        }
		/// <summary>
		/// Returns the state with the given name (if exists)
		/// </summary>
		/// <param name="name">the name of the state</param>
		/// <returns>(null if not exists)</returns>
		State GetStateByName(string name);
		/// <summary>
		/// Returns the state with the given ID (if exists)
		/// </summary>
		/// <param name="id">the id of the state</param>
		/// <returns>(null if not exists)</returns>
		State GetStateById(int id);
		/// <summary>
		/// Returns the state with the given directory state name (if exists)
		/// </summary>
		/// <param name="name">the directory state name</param>
		/// <returns>(null is not exists)</returns>
		State GetStateByDirectoryName(string name);
		/// <summary>
		/// Returns the mode with the given name (if exists)
		/// </summary>
		/// <param name="name">the name of the mode</param>
		/// <returns>(null if not exists)</returns>
		Mode GetModeByName(string name);
		/// <summary>
		/// Returns the mode with the given ID (if exists)
		/// </summary>
		/// <param name="id">the id of the mode</param>
		/// <returns>(null is not exists)</returns>
		Mode GetModeById(int id);

		/// <summary>
		/// Try to set the given state.
		/// TimeOutExcetion - if can't
		/// </summary>
		/// <param name="sender">sender</param>
		/// <param name="newState">the requested state</param>
		/// <param name="timeout">the time, while you can wait for the change</param>
		/// <param name="lockState">lock or not</param>
		/// <returns></returns>
		bool SetState(object sender, State newState, TimeSpan timeout, bool lockState);
		/// <summary>
		/// Try to set the given state (with 0 timeout).
		/// TimeOutExcetion - if can't
		/// </summary>
		/// <param name="sender">sender</param>
		/// <param name="newState">the requested state</param>
		/// <param name="lockState">lock or not</param>
		/// <returns></returns>
		bool SetState(object sender, State newState, bool lockState);
		/// <summary>
		/// Try to set the given state (with 0 timeout and without lock).
		/// TimeOutExcetion - if can't
		/// </summary>
		/// <param name="sender">sender</param>
		/// <param name="newState">the requested state</param>
		/// <returns></returns>
		bool SetState(object sender, State newState);

		/// <summary>
		/// Try to set the given mode.
		/// TimeOutExcetion - if can't
		/// </summary>
		/// <param name="sender">sender</param>
		/// <param name="newMode">the requested mode</param>
		/// <param name="timeout">the time, while you can wait for the change</param>
		/// <param name="lockState">lock or not</param>
		/// <returns></returns>
		bool SetMode(object sender, Mode newMode, TimeSpan timeout, bool lockMode);
		/// <summary>
		/// Try to set the given mode (with 0 timeout).
		/// TimeOutExcetion - if can't
		/// </summary>
		/// <param name="sender">sender</param>
		/// <param name="newMode">the requested mode</param>
		/// <param name="lockState">lock or not</param>
		/// <returns></returns>
		bool SetMode(object sender, Mode newMode, bool lockMode);
		/// <summary>
		/// Try to set the given mode (with 0 timeout and without lock).
		/// TimeOutExcetion - if can't
		/// </summary>
		/// <param name="sender">sender</param>
		/// <param name="newMode">the requested mode</param>
		/// <returns></returns>
		bool SetMode(object sender, Mode newMode);

		/// <summary>
		/// Cancellable start of the state changing
		/// </summary>
		event EventHandler<StateChangingEventArgs> StateChanging;
		/// <summary>
		/// Someone cancelled the state change
		/// </summary>
		event EventHandler<StateEventArgs> StateChangeCancelled;
		/// <summary>
		/// The state changed
		/// </summary>
		event EventHandler<StateEventArgs> StateChanged;
		/// <summary>
		/// The state locked
		/// </summary>
		event EventHandler<StateEventArgs> StateLocked;
		/// <summary>
		/// The state unlocked
		/// </summary>
		event EventHandler<StateEventArgs> StateUnlocked;

		/// <summary>
		/// Cancellable start of the mode changing
		/// </summary>
		event EventHandler<ModeChangingEventArgs> ModeChanging;
		/// <summary>
		/// Someone cancelled the mode change
		/// </summary>
		event EventHandler<ModeEventArgs> ModeChangeCancelled;
		/// <summary>
		/// The mode changed
		/// </summary>
		event EventHandler<ModeEventArgs> ModeChanged;
		/// <summary>
		/// The mode locked
		/// </summary>
		event EventHandler<ModeEventArgs> ModeLocked;
		/// <summary>
		/// The mode unlocked
		/// </summary>
		event EventHandler<ModeEventArgs> ModeUnlocked;

        event EventHandler<MessageEventArgs> MessageChanged;

	}
}
